package com.ltmonitor.web.controller.v2;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.hibernate.dialect.Ingres10Dialect;
import org.hibernate.proxy.map.MapLazyInitializer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ltmonitor.service.IQueryService;
import com.ltmonitor.util.DateUtil;
import com.ltmonitor.web.controller.command.SendTextAction;
import com.ltmonitor.web.util.JsonMessage;
import com.sun.tools.javac.tree.JCTree.LetExpr;

import net.sf.json.JSONObject;

/**
 * 自动处理主动安全报警控制器,继承自发送文本控制器
 * @author Administrator
 *
 */
@Controller
@RequestMapping("/autoProcessController")
public class AutoProcessAdasAlarmController extends SendTextAction {

	private Logger debugLog = Logger.getLogger("debug");
	
	
	//自动处理单个主动报警数据
	
	
	private int num = 0;//流水号，自动处理的报警数量
	private Map<String, ProcessObj> autoProcessMap = new HashMap<String, ProcessObj> ();//自动处理缓存
	private int canProcessNum = 3;//3次以内的重复报警可以处理
	private int removeMapTimeValue = 5;// 清除5分钟以上的map数据
	private int removeMapNumValue = 200;//当map中数据数量大于200个是开始清除
	private String queryIdAdasId = "autoProcessAdasAlarm.selectAdasIdsFromAdas";//获取主动安全报警id查询语句
	private String queryIdAlarmId = "autoProcessAdasAlarm.selectIdFromAlarm";//获取alarm报警表中 id查询语句
	
	private String[] displayOption = {"2","3"};//定义处理方式数组
	
	private int outInfoNum = 20;//每隔20个数据输出一次正常数据
	private int outInfoTimeValue = 500;//处理单个报警数据大于500毫秒的输出
	
	/**
	 * 自动处理请求
	 * @param jsonStr
	 * @return
	 */
	@RequestMapping("/autoProcess.action")
	@ResponseBody
	public JsonMessage autoProcess(@RequestBody String jsonStr){
		JsonMessage result = null;
		String msg = "";
		try {
			Map map = JSONObject.fromObject(jsonStr);
			if(map.containsKey("alarmIndex") && map.containsKey("alarmTime")){
				if(checkProcessFlg(map.get("alarmIndex").toString(), map.get("alarmTime").toString())){
					result = processOneAdasAlarmData(map);//处理单条报警
					if(result != null){
						//更新map中的数据
						updateProcessMap(map.get("alarmIndex").toString(), map.get("alarmTime").toString());		
					}
				}
			}

			if (result == null) {
				result = new JsonMessage(false, "处理失败：" + msg);
			}
		} catch (Exception e) {
			// TODO: handle exception
			msg += "自动处理失败：" + e.getMessage();
			result = new JsonMessage(false, msg);
		}
		return result;
	}

	//校验当前报警信息是否允许自动处理
	private boolean checkProcessFlg(String alarmIndex,String alarmTime){
		boolean flg = false;
		try {
			String key = alarmIndex + "_" + alarmTime;
			if(!autoProcessMap.containsKey(key)){
				//没有该key，并且时间合法，在5分钟之内,并且报警时间小于当前时间,则允许处理，
				long now = Calendar.getInstance().getTimeInMillis();
				long time = DateUtil.stringToDateTime(alarmTime).getTime();
				long cal =  (now - time) / 1000;
				if(cal >= 0 && cal < removeMapTimeValue * 60){
					flg = true;
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			debugLog.error("校验alarmIndex是否合法失败：" + e.getMessage());
		}
		return flg;
	}

	//更新处理map,直接添加
	private void updateProcessMap(String alarmIndex,String alarmTime){
		String msg = "";
		try {
			//更新数据
			String key = alarmIndex + "_" + alarmTime;
			if(!autoProcessMap.containsKey(key)){
				//没有处理过类似的
				ProcessObj obj = new ProcessObj();
				obj.num = 1;
				obj.time = Calendar.getInstance().getTimeInMillis();
				autoProcessMap.put(key, obj);
			}
			//移除超时的数据
			if(num % outInfoNum == 1){
				debugLog.info("当前报警信息缓存map数量：" + autoProcessMap.size());				
			}
			if(autoProcessMap.size() > removeMapNumValue){
				removeOuttimeMapValue();
			}
		} catch (Exception e) {
			// TODO: handle exception
			msg += "更新处理map失败：" + e.getMessage();
		}
	}
	
	//清除超时map数据
	private void removeOuttimeMapValue(){
		try {
			debugLog.info("开始清除超时map，当前map中的数量为：" + autoProcessMap.size());
			long start = Calendar.getInstance().getTimeInMillis();
			long value = Calendar.getInstance().getTimeInMillis() - removeMapTimeValue * 60 * 1000;
			Iterator<Entry<String, ProcessObj>> iterator = autoProcessMap.entrySet().iterator();
			while(iterator.hasNext())
			 { 
			  Map.Entry<String, ProcessObj> entry= iterator.next(); 
			  ProcessObj obj = entry.getValue();
				if (obj.time < value) {
//					autoProcessMap.remove(entry.getKey());
					iterator.remove();
				}
			 } 
			long end = Calendar.getInstance().getTimeInMillis();
			debugLog.info("清除超时map完成，耗时：" + (end - start) + "毫秒，当前map中的数量：" + autoProcessMap.size());
		} catch (Exception e) {
			// TODO: handle exception
			debugLog.error("清除超时map时出错:" + e.getMessage());
		}
	}
	
	
	//处理单个报警数据
	private JsonMessage  processOneAdasAlarmData(Map map){
		JsonMessage result = null;
		String msg = "";
		try {
			long start = Calendar.getInstance().getTimeInMillis();
			map.put("processed", 0);
			long[] vehicleIds = new long[1];// vehicleId
			vehicleIds[0] = Integer.valueOf(map.get("vehicleId").toString());
			
			long[] adasAlarmIds = new long[1];// adasAlarm表中的id
			long[] alarmIds = new long[1];// alarm表中的id
			
			// AdasAlarm表中的id
			List<Map<String, Object>> list = queryService.query(queryIdAdasId, map);
			if (list != null && list.size() > 0) {
				adasAlarmIds[0] = Long.valueOf(list.get(0).get("id").toString());
			} else {
				msg += "没有找到当前主动安全报警数据，无法进行自动处理";
			}
			
			// alarm表中的id
			List<Map<String, Object>> list2 = queryService.query(queryIdAlarmId, map);
			if (list2 != null && list2.size() > 0) {
				alarmIds[0] = Long.valueOf(list2.get(0).get("id").toString());
			} else {
				msg += "没有找到当前alarm报警数据，无法进行自动处理";
			}
			
			map.put("alarmIds", alarmIds);
			map.put("adasAlarmIds", adasAlarmIds);
			// 校验合法并开始处理
			if (alarmIds[0] > 0 && adasAlarmIds[0] > 0 && msg.equals("")) {
				long end = Calendar.getInstance().getTimeInMillis();
				try {
					result = sendAdasAlarms(vehicleIds, map.get("textContent").toString(), displayOption, adasAlarmIds,
							alarmIds);
					if (result.isSuccess()) {
						num++;
						if(num % outInfoNum == 1 || (end - start ) > outInfoTimeValue ){
							debugLog.info(
									"自动处理报警成功,流水号为：" + num + " ，耗时为：" + (end - start) + "  毫秒 ， 报警数据为：" + map.toString());							
						}
					} else {
						debugLog.error("自动处理报警失败：" + result.getMessage() + " ，报警数据为：" + map.toString());
					}
				} catch (Exception e) {
					debugLog.error("调用方法处理报警失败：" + e.getMessage());
					// TODO: handle exception
					result = null;
				}
				 
			}else {
				debugLog.error("自动处理报警失败：" + msg + " ， 报警数据为：" + map.toString());
			}
		} catch (Exception e) {
			// TODO: handle exception
			msg += "自动处理单条主动安全报警数据失败：" + e.getMessage();
			debugLog.error(msg);
		}
		
		return result;
	}
	
	
	
	//批量处理超过5分钟的当天报警数据
	
}

//处理map相关数据
class ProcessObj{
	public int num = 0;
	public long time = 0;
}
